package ongd.web;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import ongd.negocio.gestion.Apadrinado;
import ongd.negocio.gestion.ControladorApadrinamiento;
import ongd.negocio.gestion.PersonaContacto;
import ongd.negocio.gestion.Proyecto;
import ongd.servicios.persistencia.exceptions.PreexistingEntityException;
import org.primefaces.context.RequestContext;
import org.primefaces.event.FileUploadEvent;

/**
 * Clase que se encargará de insertar un proyecto de Apadrinamiento.
 *
 * @author <a href="mailto:egi0002@alu.ubu.es">Elena García Iglesias</a>
 * @author <a href="mailto:cms0021@alu.ubu.es">Cristina Martínez Sanz</a>
 * @version 1.0 20120124
 *
 */
@ManagedBean
@ViewScoped
public class Insertar_ProyectoApadrinamiento extends ABean {

    /**
     * Objeto de tipo ControladorApadrinamiento que nos servirá para realizar 
     * las operaciones necesarias de los apadrinamientos.
     */
    private ControladorApadrinamiento controlApadrin;
    /**
     * Objeto de tipo Proyeto que va a contener el proyecto que se va a crear.
     */
    private Proyecto proyecto;
    /**
     * Objeto de tipo PersonaContacto que va a contener la persona de contacto 
     * que se va a asociar con el proyecto.
     */
    private PersonaContacto personaContacto;
    /**
     * Objeto de tipo List que va a contener un conjunto de personas de contacto
     * que irán asociadas al proyecto.
     */
    private List<PersonaContacto> listaPersonaContacto;
    /**
     * Booleano que en función de su valor, nos indicará si debemos de insertar
     * un apadrinado o no.
     */
    private boolean insertarApadrinado;
    /**
     * Objeto de tipo Apadrinado que nos servirá para guardar un apadrinado 
     * seleccionado.
     */
    private Apadrinado apadrinado;
    /**
     * Objeto de tipo String que va a contener el título de la página donde
     * estemos.
     */
    private String titulo;

    /**
     * Contrustor de la clase.
     */
    public Insertar_ProyectoApadrinamiento() {
        SesionBean sesion = getSesionBean();
        if (sesion.iniciadaSesion()) {
            titulo = "Insertar - Nuevo Proyecto de Apadrinamiento";
            controlApadrin = sesion.getControladorApadrinamiento();
            controlApadrin.setApadrinados(new ArrayList<Apadrinado>());
            proyecto = new Proyecto();
            apadrinado = new Apadrinado();
            personaContacto = new PersonaContacto();
            proyecto.setTipo("AG");
            listaPersonaContacto = new ArrayList<PersonaContacto>();
            insertarApadrinado = false;
        }
    }

    /**
     * Método que carga los valores iniciales tras abrir un xhtml correspondiente.
     */
    @Override
    public void cargaInicial() {
    }

    /**
     * Método que sube un archivo adjunto a la aplicación.
     * @param event Fichero a subir
     */
    public void subirAdjunto(FileUploadEvent event) {
        if (getSesionBean().iniciadaSesion()) {
            try {
                String nombre;
                SimpleDateFormat sdf = new SimpleDateFormat("yyMMddHHmmss");
                nombre = sdf.format(new Date()) + "_" + event.getFile().getFileName();
                getSesionBean().guardar(nombre, event.getFile().getInputstream());
                proyecto.setDocumentoAdjunto(nombre);
            } catch (IOException ex) {
                Logger.getLogger(Insertar_Subvencion.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

    /**
     * Método que crea un proyecto. 
     * @return null
     */
    public String guardarProyecto() {
        if (getSesionBean().iniciadaSesion()) {
            RequestContext requestContext = RequestContext.getCurrentInstance();
            try {
                String resultado = controlApadrin.crearProyecto(proyecto, listaPersonaContacto);
                if (resultado.compareTo("Falta") == 0) {
                    requestContext.addCallbackParam("Falta", true);
                    return null;
                } else {
                    if (resultado.compareTo("Correcto") == 0) {
                        requestContext.addCallbackParam("Correcto", true);

                    } else {
                        if (resultado.compareTo("Repetido") == 0) {
                            requestContext.addCallbackParam("Repetido", true);
                        } else {
                            requestContext.addCallbackParam("Incorrecto", true);
                        }
                    }
                }
                //Si el resultado es incorrecto o correcto reinicio los datos
                if (resultado.compareTo("Correcto") == 0 || resultado.compareTo("Incorrecto") == 0) {
                    proyecto = new Proyecto();
                    proyecto.setTipo("AG");
                    insertarApadrinado = false;
                    listaPersonaContacto = new ArrayList<PersonaContacto>();
                    controlApadrin.setApadrinados(new ArrayList<Apadrinado>());
                }
            } catch (PreexistingEntityException ex) {
                Logger.getLogger(Insertar_ProyectoApadrinamiento.class.getName()).log(Level.SEVERE, null, ex);
            } catch (Exception ex) {
                Logger.getLogger(Insertar_ProyectoApadrinamiento.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        return null;
    }

    /**
     * Método que añade personas de contacto a la lista, siempre y cuando están tengan valores en los campos obligatorios.
     * @return null.
     */
    public String annadirPersonaContacto() {
        RequestContext requestContext = RequestContext.getCurrentInstance();
        //Insertamos en la lista de contactos si tiene valores
        if (personaContacto.getNombre().compareTo("") != 0 && personaContacto.getDireccion().compareTo("") != 0
                && personaContacto.getCargo().compareTo("") != 0 && personaContacto.getTelefono1().compareTo("") != 0) {
            //Añadimos la persona a la lista de contactos
            listaPersonaContacto.add(personaContacto);
            requestContext.addCallbackParam("PersonaOK", true);
        } else {
            requestContext.addCallbackParam("noPersona", true);
        }
        personaContacto = new PersonaContacto();
        return null;
    }

    /**
     * Método que quita una persona de contacto seleccionada de la lista.
     * @return null
     */
    public String quitarPersonaContacto() {
        listaPersonaContacto.remove(personaContacto);
        return null;
    }

    /**
     * Método que permite insertar apadrinados o no en función del tipo de proyecto.
     * @return null.
     */
    public String insertarApadrinado() {
        if (proyecto.esProyectoApadrinamientoGeneral()) {
            proyecto.setTipo("AP");
            insertarApadrinado = true;
        } else {
            proyecto.setTipo("AG");
            insertarApadrinado = false;
            //Ponemos la lista de apadrinados a vacia
            controlApadrin.setApadrinados(new ArrayList<Apadrinado>());
        }
        return null;
    }

    /**
     * Método que quita un apadrinado seleccionado de la lista de apadrinados.
     * @return null
     */
    public String quitarApadrinado() {
        controlApadrin.getApadrinados().remove(apadrinado);
        return null;
    }

    /**
     * Método que devuelve el proyecto.
     * @return proyecto.
     * @see #setProyecto
     */
    public Proyecto getProyecto() {
        return proyecto;
    }

    /**
     * Método que asigna un nuevo valor de proyecto.
     * @param proyecto nuevo valor. 
     * @see #getProyecto
     */
    public void setProyecto(Proyecto proyecto) {
        this.proyecto = proyecto;
    }

    /**
     * Método que devuelve la persona de contacto.
     * @return persona de contacto.
     * @see #setPersonaContacto
     */
    public PersonaContacto getPersonaContacto() {
        return personaContacto;
    }

    /**
     * Método que da un nuevo valor a la persona de contacto.
     * @param personaContacto nuevo valor. 
     * @see #getPersonaContacto
     */
    public void setPersonaContacto(PersonaContacto personaContacto) {
        this.personaContacto = personaContacto;
    }

    /**
     * Método que devuelve la lista de personas de contacto.
     * @return lista de personas de contacto.
     * @see #setListaPersonaContacto
     */
    public List<PersonaContacto> getListaPersonaContacto() {
        return listaPersonaContacto;
    }

    /**
     * Método que asigna un nuevo valor a la lista de personas de contacto.
     * @param listaPersonaContacto nueva lista.
     * @see #getListaPersonaContacto
     */
    public void setListaPersonaContacto(List<PersonaContacto> listaPersonaContacto) {
        this.listaPersonaContacto = listaPersonaContacto;
    }

    /**
     * Método que devuelve el controlador de apadrinamiento.
     * @return control de apadrinamiento.
     */
    public ControladorApadrinamiento getControlApadrin() {
        return controlApadrin;
    }

    /**
     * Método que devuelve el valor de la variable insertarApadrinado.
     * @return valor de la variable.
     */
    public boolean isInsertarApadrinado() {
        return insertarApadrinado;
    }

    /**
     * Método que da un nuevo valor a la variable insertarApadrinado.
     * @param insertarApadrinado nuevo valor. 
     */
    public void setInsertarApadrinado(boolean insertarApadrinado) {
        this.insertarApadrinado = insertarApadrinado;
    }

    /**
     * Método que devuelve el valor de la variable apadriando.
     * @return apadrinado
     * @see #setApadrinado
     */
    public Apadrinado getApadrinado() {
        return apadrinado;
    }

    /**
     * Método que establece un nuevo valor a la variable apadrinado.
     * @param apadrinado Nuevo valor de la variable
     * @see #getApadrinado
     */
    public void setApadrinado(Apadrinado apadrinado) {
        this.apadrinado = apadrinado;
    }

    /**
     * Método que devuelve el valor de la variable titulo.
     * @return titulo
     * @see #setTitulo
     */
    public String getTitulo() {
        return titulo;
    }

    /**
     * Método que establece el valor de la variable título.
     * @param titulo Nuevo valor de la variable
     * @see #getTitulo
     */
    public void setTitulo(String titulo) {
        this.titulo = titulo;
    }
}